package com.hanklee.demo.utils

import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import androidx.annotation.RequiresPermission
import androidx.lifecycle.LifecycleCoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class AudioRecorder(private val lifecycleScope: LifecycleCoroutineScope) {

    private val SAMPLE_RATE = 16000 // 16KHz
    private val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO
    private val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT // 16-bit PCM
    private val BUFFER_SIZE =
        AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT)

    private var audioRecord: AudioRecord? = null
    private var isRecording = false

    @RequiresPermission(value = "android.permission.RECORD_AUDIO")
    fun startRecording(
        recorderListener: (data: ByteArray, bytesRead: Int, byteSize: Int) ->
        Unit,
    ) {
        if (isRecording) {
            return
        }

        audioRecord = AudioRecord(
            MediaRecorder.AudioSource.MIC,
            SAMPLE_RATE,
            CHANNEL_CONFIG,
            AUDIO_FORMAT,
            BUFFER_SIZE
        )

        if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) {
            return
        }

        lifecycleScope.launch(Dispatchers.IO) {
            audioRecord?.startRecording()
            isRecording = true
            while (isRecording) {
                val buffer = ByteArray(BUFFER_SIZE)
                val bytesRead = audioRecord?.read(buffer, 0, BUFFER_SIZE) ?: 0
                if (bytesRead > 0) {
                    recorderListener(buffer, bytesRead, BUFFER_SIZE)
                }
            }
        }
    }

    fun stopRecording() {
        isRecording = false
        audioRecord?.stop()
        audioRecord?.release()
    }
}
